package com.bonc.apicreator.ctrl;


import java.io.IOException;
import java.text.ParseException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpSession;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Controller;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSON;
import com.bonc.apicreator.codebuild.action.CodeBuildAction;
import com.bonc.apicreator.codebuild.action.WarBuildAction;
import com.bonc.apicreator.constant.BaseConstant;
import com.bonc.apicreator.dao.ApiDao;
import com.bonc.apicreator.dao.ApiRequestDao;
import com.bonc.apicreator.dao.ApiResponseDao;
import com.bonc.apicreator.dao.ProjectDao;
import com.bonc.apicreator.dao.RowKeyDao;
import com.bonc.apicreator.dao.SqlDao;
import com.bonc.apicreator.entity.Project;
import com.bonc.apicreator.entity.RestApi;
import com.bonc.apicreator.entity.RestApiRequest;
import com.bonc.apicreator.entity.RestApiResponse;
import com.bonc.apicreator.entity.RowKey;
import com.bonc.apicreator.entity.SqlSentence;
import com.bonc.apicreator.entity.User;


/**
 * project的controller
 *
 * @author gaopengyu
 * @version 2016年8月5日
 * @see ProjectController
 * @since
 */
@Controller
@RequestMapping("/project")
public class ProjectController {
    /**
     * 日志对象
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(ProjectController.class);

    /**
     * projectDao
     */
    @Autowired
    private ProjectDao projectDao;

    /**
     * apiDao
     */
    @Autowired
    private ApiDao apiDao;

    /**
     * requestDao
     */
    @Autowired
    private ApiRequestDao requestDao;

    /**
     * responseDao
     */
    @Autowired
    private ApiResponseDao responseDao;

    /**
     * rowKeyDao
     */
    @Autowired
    private RowKeyDao rowKeyDao;

    /**
     * SqlDao
     */
    @Autowired
    private SqlDao sqlDao;
    
    /**
     * 构建代码对象
     */
    @Autowired
    private CodeBuildAction codeBuildAction;

    /**
     * 打成war包
     */
    @Autowired
    private WarBuildAction warBuildAction;

    /**
     * Description: 分页前加载页面
     * 
     * @return String
     * @see
     */
    @RequestMapping(value = "")
    public String page() {
        return "project/list.jsp";
    }

    /**
     * Description: ajax请求数据
     * 
     * @param pageable
     * @param condition
     * @param userId
     * @return Object
     * @see
     */
    @RequestMapping(value = {"/list"})
    @ResponseBody
    public Object list(Pageable pageable, String condition, Long userId) {
        Map<String, Object> map = new HashMap<String, Object>();
        Page<Project> proList;
        if (StringUtils.isEmpty(condition)) {
            proList = projectDao.findByCreateByOrderByCreateDateDesc(userId, pageable);
        }
        else {
            proList = projectDao.findByCreateByAndNameContainingOrderByCreateDateDesc(userId,
                condition, pageable);
        }
        map.put("list", proList.getContent());
        map.put("count", proList.getTotalElements());
        map.put("code", BaseConstant.STATE_SUCCESS);
        LOGGER.debug("list response:" + JSON.toJSONString(proList.getContent()));
        return JSON.toJSONString(map);
    }

    /**
     * Description: 生成代码
     * 
     * @param id
     * @return Object
     * @see
     */

    @RequestMapping(value = {"/buildProject/{id}"})
    @ResponseBody
    public Object buildProject(@PathVariable Long id) {
        Map<String, Object> map = new HashMap<String, Object>();
        Project project = projectDao.findOne(id);
        if (project == null) {
            map.put("code", BaseConstant.STATE_NOFOUND);
        }
        else {

            List<RestApi> apis = apiDao.findByProId(id);
            if (!CollectionUtils.isEmpty(apis)) {

                for (RestApi restApi : apis) {

                    List<RestApiRequest> apiMethodParas = requestDao.findByApiIdOrderByDataTypeDesc(
                        restApi.getId());
                    restApi.setParams(apiMethodParas);

                    List<RestApiResponse> apiMethodReturnVal = responseDao.findByApiId(
                        restApi.getId());
                    restApi.setReturnValue(apiMethodReturnVal);

                    RowKey rowKey = rowKeyDao.findByApiId(restApi.getId());
                    restApi.setRowKey(rowKey);
                    
                    SqlSentence sqlSentence = sqlDao.findByApiId(restApi.getId());
                    restApi.setSqlSentence(sqlSentence);
                }

                project.setApis(apis);

                LOGGER.info("project ......." + JSON.toJSONString(project));

                codeBuildAction.build(project);
                map.put("code", BaseConstant.STATE_SUCCESS);
            }
            else {
                map.put("code", BaseConstant.STATE_NOFOUND);
            }
        }
        return JSON.toJSONString(map);
    }

    /**
     * Description: 打成war包
     * 
     * @param id
     * @return json
     * @throws IOException
     *             Object
     * @see
     */
    @RequestMapping(value = {"/buildPackage/{id}"})
    @ResponseBody
    public Object buildPackage(@PathVariable Long id)
        throws IOException {
        Project project = projectDao.findOne(id);
        Map<String, Object> map = new HashMap<String, Object>();
        if (project == null) {
            map.put("code", BaseConstant.STATE_NOFOUND);
        }
        else {
            String userId = project.getCreateBy().toString();
            String proName = project.getCode();
            warBuildAction.buildWar(userId, proName);
            map.put("code", BaseConstant.STATE_SUCCESS);
        }
        return JSON.toJSONString(map);
    }

    /**
     * Description: 添加工程
     * 
     * @param project
     * @return String
     * @throws ParseException
     *             String
     * @see
     */
    @RequestMapping(value = {"/save"}, method = RequestMethod.POST)
    public String add(Project project) {
        String context = project.getCode();
        if (!context.contains("/")) {
            context = "/" + context;
        }
        project.setContext(context);
        project.setCreateDate(new Date());
        projectDao.save(project);
        return "redirect:/project";
    }

    /**
     * Description: 删除工程
     * 
     * @param id
     * @return String
     * @see
     */
    @RequestMapping(value = {"/delete"}, method = RequestMethod.POST)
    @ResponseBody
    public Object delete(Long id) {
        projectDao.delete(id);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("code", BaseConstant.STATE_SUCCESS);
        return map;
    }

    /**
     * Description: 更新时先查询这条数据
     * 
     * @param id
     * @return Object
     * @see
     */
    @RequestMapping(value = {"/findOne"})
    @ResponseBody
    public Object findOne(Long id) {
        Project project = projectDao.findOne(id);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("code", BaseConstant.STATE_SUCCESS);
        map.put("message", "成功");
        map.put("project", project);
        return map;
    }

    /**
     * Description: 更新 目前更新包名、描述和hbase相关信息
     * 
     * @param project
     * @return String
     * @see
     */
    @RequestMapping(value = {"/update"}, method = RequestMethod.POST)
    public String update(HttpSession session, Project project) {
        LOGGER.info(JSON.toJSONString(project));
        Project pro = projectDao.findOne(project.getId());
        User user = (User)session.getAttribute("user");
        if (!StringUtils.isEmpty(project)) {
            String context;
            String code = project.getCode();
            if (!code.startsWith("/")) {
                context = "/" + code;
            }
            else {
                context = code;
            }
            project.setContext(context);
            project.setTextOnly(pro.isTextOnly());
            project.setCreateBy(pro.getCreateBy());
            project.setCreateDate(pro.getCreateDate());
            project.setUpdateBy(user.getId());
            project.setUpdateDate(new Date());
            projectDao.save(project);
        }
        return "redirect:/project";
    }

    /**
     * Description: 重名校验
     * 
     * @param name
     * @param userId
     * @param id
     * @return Object
     * @see
     */
    @RequestMapping(value = {"/checkName"})
    @ResponseBody
    public Object checkName(String name, Long userId, String id) {
        Project project = null;
        if ("pro_name".equals(id)) {
            project = projectDao.findByNameAndCreateBy(name, userId);
        }
        if ("pro_code".equals(id)) {
            project = projectDao.findByCodeAndCreateBy(name, userId);
        }
        if ("pro_context".equals(id)) {
            name = "/" + name;
            project = projectDao.findByContextAndCreateBy(name, userId);
        }
        Map<String, Object> map = new HashMap<String, Object>();
        if (!StringUtils.isEmpty(project)) {
            map.put("code", BaseConstant.STATE_CHONGFU);
            map.put("message", "已存在！");
        }
        return map;
    }
}